<?php

/**
 * CFprocess is a class to simplfy processing of Databse CRUD (Create Remove Update Delete) Tables
 *
 * @package CFtable
 */

class CFprocess {

	var $maintable;
	var $fieldspec;
	var $newvalues;
    var $oldvalued;
	var $addtype = 'button';

    var $keys;
	
    // This is the variable to use for a forced after-process page
    // not implemented yet.. just an idea
    var $ap_var;

	var $pageafteradd;
	var $pageaftersave;
	var $pageafterdelete;
	var $pageforedit = 'defuaultedit.php';
	//var $hashsalt = 'Change this default salt 0394ufw90w';

    var $actval_prefix = '';
    var $oldval_prefix = 'OV';


    var $mode_save = 'Save';
    var $mode_delete = 'Delete';
    var $mode_duplicate = 'Copy';
	
	// $newvalues[<colname>] = <value>

	function CFprocess($thespec = '', $listpage = 'default_list.php'){
		$this->fieldspec = $thespec;
		
		$this->pageafteradd = $listpage;
		$this->pageaftersave = $listpage;
		$this->pageafterdelete = $listpage;

		
	}

	function set_fieldspec($thespec){
		$this->fieldspec = $thespec;
	}

	function set_maintable($thetablename){
		$this->maintable = $thetablename;
	}

	
	function on_get_newvalues(){
	
	}
	
    /**
	 *
	* get_newvalues will fill the $this->newvalues with values for each past action variable ( use in adds and saves) where 
	* creates newvalues array key by column name (as defined in fieldspec) value = value from $_REQUEST
	 * $newvalues[$col_name] = value
	 */	
	function get_newvalues(){
		foreach($this->fieldspec AS $col_name => $colspec){
            if(isset($_REQUEST[$this->actval_prefix .$col_name])){
				$this->newvalues[$col_name] = urldecode($_REQUEST[$this->actval_prefix . $col_name]);
			}
		}
		$this->on_get_newvalues();
        $this->get_keys();
	}

    /**
	 *
	 * get_keys will fill the $this->keys array with values for each key
	 * in the fieldspec, if they are defined.  Returns true for all keys found, false if not.
	 *
	 */
	function get_keys(){
	$foundall = true;
    foreach ($this->fieldspec as $col_name => $colspec){
        
        if(!empty($colspec['key'])){
            if((isset($_REQUEST[$col_name])) AND ($_REQUEST[$col_name] != '') ){
                $this->keys[$col_name] = $_REQUEST[$col_name];
                }else{
                   $foundall = false;
                }
            }
		}
		return $foundall;
	}

    /**
	 *get_oldvalues()
	 * Set old values to values defined in request.  If a non-enpty REQUEST variable exists for the column, set value in $oldvalues[$col_name] = value
	 * in the fieldspec, if they are defined.  Returns true for all keys found, false if not.
	 *
	 */
	function get_oldvalues(){
		foreach($this->fieldspec AS $col_name => $colspec){
			if(isset($_REQUEST[$this->oldval_prefix . $col_name]) AND $_REQUEST[$this->oldval_prefix . $col_name] !== ""){
				$this->oldvalues[$col_name] = $_REQUEST[$this->oldval_prefix .$col_name];
			}
		}
		$this->on_get_oldvalues();
	}
    
	function doescape($input){
		return addslashes($input);
		}
		
    /**
	 *get_next_auto_id($column, $iskey=true)
	 * Set old values to values defined in request.  If a non-enpty REQUEST variable exists for the column, set value in $oldvalues[$col_name] = value
	 * in the fieldspec, if they are defined.  Returns true for all keys found, false if not.
	 *
	 */	
	function get_next_auto_id($column, $iskey=true){
        if (isset($this->fieldspec[$column]['source'])){
            $table = $this->fieldspec[$column]['source'];
        }else{
            $table = $this->maintable;
        }
        // NEED TO CHANGE this from 1 to the source table filter (maybe not.. ct2009-03-14)
        $next_id = get_max_value ($column, $table, 1) + 1;
        $this->newvalues[$column] = $next_id;
        if($iskey){
            $this->keys[$column] = $next_id;
            }
		return $next_id;
	
	}



	function process_New(){
        foreach($this->fieldspec AS $col_name => $colspec){
		// for input values, accept only non empty values.
            if(!empty($this->newvalues[$col_name]) OR $this->newvalues[$col_name] === '0'){
				$thisval = $this->newvalues[$col_name];
				//$thisval = addslashes($thisval);
				($vars=='')?$vars=$col_name:$vars.=",$col_name";
				($vals=='')?$vals = "'" . $thisval . "'":$vals .= ",'" . $thisval . "'";
				}
				// If we no data sent for this variable and it is a key, get new value
			else if(!empty($colspec['key'])){
				($vars=='')?$vars=$col_name:$vars.=",$col_name";
				($vals=='')?$vals = $this->get_next_auto_id($col_name):$vals .= "," . $this->get_next_auto_id($col_name);
				}
            }
        if($vars != ''){
            $qry_insert = "INSERT INTO $this->maintable ($vars) VALUES ($vals)";
            do_query($qry_insert);
            }	
	}

	function process_Add(){
		$this->process_New();
	}

	// CT 2009-10-22 Redirected this to process_New since they were redundant.  Only difference is:
	// Procss_Add checked that a value had !empty in either [add] or [filter] for it to be able to add. New does not
	function OLDprocess_Add(){
        $col_list = "";
        $value_list = "";
		foreach($this->fieldspec AS $col_name => $colspec){
            
			if (!empty($colspec['key'])){
				if(empty($this->newvalues[$col_name] )){ // key but no data provided
					// CT 2009-05-28 Changed from !isset to empty so we get key on above.  NEED TO check newvalues gathering
                    $value = $this->get_next_auto_id($col_name); // get next id

                }else{
                    $value = $this->newvalues[$col_name]; // key with data
                    //$value = addslashes($value);
                }// add to col_list, with comma if not the first
                if($col_list == ""){
                    $col_list .= $col_name;
                }else{
                    $col_list .= ", $col_name";
                }

                if($value_list == ""){
                    $value_list .= "'$value'";
                }else{
                    $value_list .= ", '$value'";
                }

			}elseif (!empty($colspec['add']) OR !empty($colspec['filter']) ){// not a key but in add spec
                if(isset($this->newvalues[$col_name])){
                    $value = $this->newvalues[$col_name]; // with data
                   // $value = addslashes($value);
                if($col_list == ""){    
                    $col_list .= $col_name;
                }else{
                    $col_list .= ", $col_name";
                }     
                
                if($value_list == ""){    
                    $value_list .= "'$value'";
                }else{
                    $value_list .= ", '$value'";
                }                 
                
            } // value was passed for adding (add)
		} // value was in add spec

        }
        $qry_add = "INSERT INTO $this->maintable ($col_list) VALUES ($value_list)";
		do_query($qry_add);
    }


	function process_Save(){
		$needcomma = 0;
		$execute_query = 0;
		//print 'In Save:';
		//print "fulltime = " . $this->newvalues[fulltime] . "<br>\n";
		foreach($this->fieldspec AS $col_name => $colspec){
			//if((!empty($this->newvalues[$col_name])) OR (string)$this->newvalues[$col_name] === '0'){
			if(isset($this->newvalues[$col_name])){
				$setvalue = $this->newvalues[$col_name];
               // $setvalue = addslashes($setvalue);
                if($needcomma == 0){
					$sets .= "$col_name = ";
					$sets .= "'" . $this->doescape($this->newvalues[$col_name]) . "'";
					$needcomma = 1;
					}
				else{
					$sets.= ", $col_name = ";
					$sets .= " '" . $this->doescape($this->newvalues[$col_name]) . "'";	
				}
				$execute_query = 1;
			}
			
		}	
		$needcomma = 0;
		if($execute_query == 1){
		//$execute_query = 0; // reset to 0 again, needs to have at least one key
		foreach($this->fieldspec AS $col_name => $colspec){
			//print 'in colspecs';
			if (!empty($colspec['key'])){
				if($needcomma == 0){
					$where .= " $col_name = ";
					$where .= "'" . $this->doescape($this->newvalues[$col_name]) . "'";
					$needcomma = 1;
					}
				else{
					$where .= " AND $col_name = ";
					$where .= " '" . $this->doescape($this->newvalues[$col_name]) . "'";	
			
				}
				$execute_query = 1;
			} // col is key column

		} // end foreach fieldspec column	
		} // end execute query check (so far)
		if($execute_query == 1){
		
			$qry_update = "UPDATE $this->maintable SET $sets WHERE 0 OR ( $where ) ";
			//print "GOT HERE" . $qry_update;
            do_query($qry_update);
			
		}
	
	}	
	

	function process_Delete(){
		$needcomma = 0;
		$execute_query = 0;
		foreach($this->fieldspec AS $col_name => $colspec){
			//print 'in colspecs';
			if (!empty($colspec['key'])){
				if($needcomma == 0){
					$where .= "$col_name = ";
					$where .= "'" . $this->doescape($this->newvalues[$col_name]) . "'";
					$needcomma = 1;
					}
				else{
					$where .= " AND $col_name = ";
					$where .= " '" . $this->newvalues[$col_name] . "'";	
			
				}
				$execute_query = 1;
			} // col is key column
		} // end foreach fieldspec column	
		
		if($execute_query == 1){
		
			$qry_delete = "DELETE FROM $this->maintable WHERE 0 OR ( $where ) ";
			do_query($qry_delete);
			//print $qry_delete;
		}
	
	}	

function process_update(){

	if (isset($_REQUEST['rqkeyvalues'])) {
		$CV_rqkeyvalues = $_REQUEST['rqkeyvalues'];
		$CV_keyvals = explode(",", $CV_rqkeyvalues);
		$executequery = true;
		}
	else {
		$executequery = false;
	}

	if (isset($_REQUEST['rqkeyvariables'])) {
		$CV_rqkeyvariables = $_REQUEST['rqkeyvariables'];
		$CV_keyvars = explode(",", $CV_rqkeyvariables);
	}
	else {
		$CV_rqkeyvariables = 0;
		$executequery = false;
	}	


	$CV_filter = '';
	$CV_needAND = 0;
	foreach($CV_keyvars as $CV_key=>$CV_variable){
	//print "<br> CV_variable = $CV_variable <br>";
		$CV_quote = '\'';
		if(!empty($CV_variable)){
			$CV_value = $CV_keyvals[$CV_key];
			//$CV_quote = $CV_varquote['lastName'];
			if($CV_needAND == 0){
				$CV_filter = " $CV_variable = '$CV_value'";
				$CV_needAND = 1;
				}
			else{
				$CV_filter .= " AND $CV_variable = '$CV_value' ";
			}
		}
	}

	$CV_table = $this->maintable;

	if($executequery){

		$qry_change = "UPDATE $CV_table SET " . $_REQUEST['var'] . " = '" . $_REQUEST['value'] . "' WHERE 0 OR ($CV_filter)";
		//print $qry_change;
		$result = do_query($qry_change);

		if($result == 1){
			echo "Success";
		}
		else{
			echo "Result:$result";	
		}
	exit;
	}
	else{
	echo 'query not executed';
	exit;
	}
}
    // Note this could be writtne like multichange to do all in one query, but
    // this works for now.
	function process_Multidelete(){
	// get key values
	$rk_index = 0;
		if(!empty($_REQUEST['seltrans']) OR $_REQUEST['seltrans'] === 0){
			$keyvalsets = explode(";", $_REQUEST['seltrans']);

			foreach($this->fieldspec AS $col_name => $colspec){
					if (!empty($colspec['key'])){
						$rowkeys[$rk_index] = $col_name;
						$rk_index ++;
					}
			}

	// put together queries
	//print "<br> keyvalsets:<br>\n";
	//print_r($keyvalsets);
	//print "<br> rowkeys:<br>\n";
	//print_r($rowkeys);
	
			foreach($keyvalsets AS $thekeyvalset){
			$kv_index = 0;
			$where = '';
			
			$keyvalues = explode(",", $thekeyvalset);
			
				foreach($rowkeys AS $thekey){
					
					if($kv_index != 0){
						$where .= " AND ";
						}
					$where .= " $thekey = '" . $keyvalues[$kv_index] . "' ";
					$kv_index ++;
				}// end for each rowkey
				$qry_del = "DELETE FROM $this->maintable WHERE 0 OR ($where)";
				do_query($qry_del);
				//print $qry_del . "\n <br>";
			}// end for each keyvalset
		}
	}
	// This function was re-written on 2008-12-23
    // seems like something was wrong with the old one, but not sure.
	function process_Multichange(){
		$rk_index = 0;
        $needcomma = 0;
		$dochange = false;
		if(!empty($_REQUEST['seltrans']) OR $_REQUEST['seltrans'] === 0){
			
            // form array of keys, (with multiple keys seperated by commas)
            $keyvars_need_comma = false;
			foreach($this->fieldspec AS $col_name => $colspec){
					if (!empty($colspec['key'])){
                        if($keyvars_need_comma){
                            $keyvars .= ',' .$col_name;
                        }else{
                            $keyvars .= $col_name;
                        }
					}
			}

        $need_kvset_comma = false;
        $ar_keyvalsets = explode(";", $_REQUEST['seltrans']);

        $keyvals .= '(';
        foreach($ar_keyvalsets AS $ar_thekeyvalset){
			$kv_index = 0;
			$where = '';
            if($need_kvset_comma){
                $keyvals .= ',';
            }
            $need_kvset_comma = true;
			$ar_keyvalues = explode(",", $ar_thekeyvalset);
            $need_key_comma = false;
            $keyvals .= '(';
            foreach($ar_keyvalues AS $keyvalue){
                if($need_key_comma){
                    $keyvals .= ",'" . $keyvalue . "'";
                }else{
                    $keyvals .= "'" . $keyvalue . "'";
                    $need_key_comma = true;
                }
            }
            $keyvals .= ')';
         }
         $keyvals .= ')';



        foreach($this->fieldspec AS $col_name => $colspec){
            if($_REQUEST['IS_CHG_' . $col_name] == 1){
				$dochange = true;
                if($needcomma == 0){
                    $sets .= "$col_name = ";
                    $sets .= "'" . $this->doescape($this->newvalues[$col_name]) . "'";
                    $needcomma = 1;
                    }
                else{
                    $sets.= ", $col_name = ";
                    $sets .= " '" . $this->newvalues[$col_name] . "'";
                }
            }
        }
		if($dochange){
            $qry_change = "UPDATE $this->maintable SET $sets  WHERE 0 OR ($keyvars IN $keyvals)";
            //print $qry_change;
            do_query($qry_change);
            //exit;
			}
		} // multikey element is not empty
	}// end function

	function do_actions(){
        $this->on_pre_action();
		//print "In do_actions Mode= " . $_REQUEST['mode'] ;
		switch ($_REQUEST['mode']) {
		case 'Add':
            $this->addtype = $_REQUEST['addtype'];
			$this->get_newvalues();
            $this->on_pre_add();
		    $this->process_Add();
            $this->on_post_add();
            $header_text = "Location: $this->pageafteradd";
			header($header_text); /* Redirect browser */
            break;
        case 'New':
            $this->get_newvalues();
            $this->on_pre_new();
            $this->process_New();
            $this->on_post_new();
            $header_text = "Location: $this->pageafteradd";
			header($header_text); /* Redirect browser */
            break;            
		case $this->mode_delete:
			$this->get_newvalues();
            $this->on_pre_delete();
		    $this->process_Delete();
            $this->on_post_delete();
			$header_text = "Location: $this->pageafterdelete"; 
			header($header_text); /* Redirect browser */ 
		    break;
		case 'Save Row':
		case $this->mode_save:
			$this->get_newvalues();
            $this->on_pre_save();
		    $this->process_Save();
            $this->on_post_save();
			$header_text = "Location: $this->pageaftersave"; 
			header($header_text); /* Redirect browser */ 
			exit;
		    break;
		case 'Edit':
		case $this->mode_edit:
			$this->get_newvalues();
            $this->on_edit();
			foreach($this->keys AS $thevar => $thevalue){
				($urlkey == '')?$urlkey = '?' . $thevar . '=' . $thevalue:$urlkey = '&' . $thevar . '=' . $thevalue;
			}
		    $header_text = "Location: $this->pageforedit$urlkey"; 
			header($header_text); /* Redirect browser */ 
			exit;
		    break;			
		case 'Multidelete':
            $this->on_pre_multidelete();
		    $this->process_Multidelete();
            $this->on_post_multidelete();
			$header_text = "Location: $this->pageafterdelete"; 
			header($header_text); /* Redirect browser */ 		
			exit;
		    break;
		case 'Multichange':
		    $this->get_newvalues();
            $this->on_pre_multichange();
			$this->process_Multichange();
            $this->on_post_multichange();
			$header_text = "Location: $this->pageaftersave"; 
			header($header_text); /* Redirect browser */ 	
			exit;
		    break;
		case 'update':
			$this->process_update();
			break;
        }
    }

 function on_pre_action(){}
 function on_post_action(){}

 function on_pre_delete(){}
 function on_post_delete(){}

 function on_pre_save(){}
 function on_post_save(){}

 function on_edit(){}

 function on_pre_add(){}
 function on_post_add(){}

 function on_pre_new(){}
 function on_post_new(){}

 function on_pre_multichange(){}
 function on_post_multichange(){}

 function on_pre_multidelete(){}
 function on_post_multidelete(){}
	
}
?>